"""
https://mp.weixin.qq.com/s/UM6PwoBGhRGvJbvUYggObw

MCP从编程模型的角度来看，本质上是一种有状态的双向RPC（远程过程调用）模型，结合了事件驱动和请求-响应的特性。
这种混合模式使其在AI应用与外部系统集成方面具有独特优势。

MCP的核心特征包括：

1.有状态会话：与传统无状态REST API不同，MCP维护会话状态，客户端和服务器之间建立长期连接，会话具有明确的生命周期。

2.双向通信：不仅客户端可以调用服务器（传统RPC模式），服务器也可以调用客户端（反向RPC）。例如，服务器可以请求客户端执行AI采样。

3.基于能力的协商：初始化阶段进行能力协商，动态发现可用功能，适应不同实现和版本。

4.事件通知机制：支持单向通知，资源变更订阅模式，异步事件处理。

5.标准化接口：定义了一组标准操作，使用JSON Schema定义参数和返回值，促进互操作性。
"""
import asyncio
import uuid
from typing import Optional

from fastapi import FastAPI, Request
from pydantic import BaseModel
from sse_starlette.sse import EventSourceResponse

app = FastAPI()
mcpHub = {}


class McpRequest(BaseModel):
    id: Optional[int] = None
    jsonrpc: str
    method: str
    params: Optional[dict] = None


class MCPServer:
    def __init__(self):
        self.queue = asyncio.Queue()

    async def reader(self):
        while True:
            event = await self.queue.get()
            yield event

    async def request(self, payload: McpRequest):
        if payload.method == "initialize":
            await self.queue.put({"event": "message", "data": "这是初始化数据"})
        elif payload.method == "tools/list":
            print("tools/list")


@app.get("/sse")
async def sse():
    client_id = str(uuid.uuid4())
    mcp = MCPServer()
    mcpHub[client_id] = mcp
    await mcp.queue.put({"event": "endpoint", "data": f"/message?client_id={client_id}"})
    return EventSourceResponse(mcp.reader())


@app.post("/message")
async def message(request: Request, payload: McpRequest):
    client_id = request.query_params.get("client_id")
    if client_id not in mcpHub:
        return "no client"
    await mcpHub[client_id].request(payload)
    return "ok"
